package cz.cvut.kadledav.paa.weight3sat.util;

import cz.cvut.kadledav.paa.weight3sat.bo.Instance;
import net.sf.corn.cps.CPScanner;
import net.sf.corn.cps.ResourceFilter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * User: David Kadlecek
 * Date: 30.12.13
 */
public class InstanceLoader {

    public static List<Instance> loadInstances(int clausesSize){

        List<URL> resources = CPScanner.scanResources(new ResourceFilter().resourceName("CBS*n100*.cnf"));
        List<Instance> instances = new ArrayList<>();
        for (URL resourceURL : resources) {
            try(BufferedReader file = new BufferedReader(new FileReader(resourceURL.getFile()))){
                Instance instance = null;
                String line = file.readLine();
                for (;line != null && !line.trim().isEmpty();line = file.readLine()) {
                    if(line.startsWith("c"))continue;
                    StringTokenizer tokenizer = new StringTokenizer(line);
                    if(line.startsWith("p")){
                        tokenizer.nextToken();  // p
                        tokenizer.nextToken();  // cnf
                        final String middleString = resourceURL.toString().substring(resourceURL.toString().lastIndexOf("_b50_") + 5);
                        final int id = Integer.parseInt(middleString.substring(0, middleString.indexOf('.')));
//                        assertThat(resourceURL.toString().substring(resourceURL.toString().lastIndexOf("_b50_") + 5)).contains(String.valueOf(id));
                        final int numOfVariables = Integer.parseInt(tokenizer.nextToken());
                        int[] weights = new int[numOfVariables];
                        instance = new Instance(id, numOfVariables,clausesSize);
                        for (int i = 0; i < numOfVariables ; i++) {
                            weights[i] = i+1;
                        }
                        instance.setWeights(weights);
                        continue;
                    }
                    boolean added = instance.add3LiteralsToClause(Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()));
                    if(!added){
                        break;
                    }
                }
                instances.add(instance);
            } catch (IOException  e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        return instances;
    }


    public static List<Instance> loadInstances50(int clausesSize){

        List<URL> resources = CPScanner.scanResources(new ResourceFilter().resourceName("uf50-*.cnf"));
        List<Instance> instances = new ArrayList<>();
        for (URL resourceURL : resources) {
            try(BufferedReader file = new BufferedReader(new FileReader(resourceURL.getFile()))){
                Instance instance = null;
                String line = file.readLine();
                for (;line != null && !line.trim().isEmpty();line = file.readLine()) {
                    if(line.startsWith("c"))continue;
                    StringTokenizer tokenizer = new StringTokenizer(line);
                    if(line.startsWith("p")){
                        tokenizer.nextToken();  // p
                        tokenizer.nextToken();  // cnf
                        final String middleString = resourceURL.toString().substring(resourceURL.toString().lastIndexOf("uf50-") + 5);
                        final int id = Integer.parseInt(middleString.substring(0, middleString.indexOf('.')));
//                        assertThat(resourceURL.toString().substring(resourceURL.toString().lastIndexOf("_b50_") + 5)).contains(String.valueOf(id));
                        final int numOfVariables = Integer.parseInt(tokenizer.nextToken());
                        int[] weights = new int[numOfVariables];
                        instance = new Instance(id, numOfVariables,clausesSize);
                        for (int i = 0; i < numOfVariables ; i++) {
                            weights[i] = i+1;
                        }
                        instance.setWeights(weights);
                        continue;
                    }
                    boolean added = instance.add3LiteralsToClause(Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()));
                    if(!added){
                        break;
                    }
                }
                instances.add(instance);
            } catch (IOException  e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        return instances;
    }

    public static List<Instance> loadInstancesOwn(int clausesSize, int variables){

        List<URL> resources = CPScanner.scanResources(new ResourceFilter().resourceName("*n"+variables+"_c"+clausesSize+"*.custom.cnf"));
        if(resources.isEmpty()){
            throw new RuntimeException("Nothing found");
        }
        List<Instance> instances = new ArrayList<>();
        for (URL resourceURL : resources) {
            try(BufferedReader file = new BufferedReader(new FileReader(resourceURL.getFile()))){
                Instance instance = null;
                String line = file.readLine();
                int knowSolution = -1;
                for (;line != null && !line.trim().isEmpty();line = file.readLine()) {
                    if(line.startsWith("c")){
                        if(line.contains("Known solution cost is")){
                            final String[] split = line.split("\\s+");
                            knowSolution = Integer.parseInt(split[split.length - 1]);
                        }
                        continue;
                    }
                    StringTokenizer tokenizer = new StringTokenizer(line);
                    if(line.startsWith("p")){
                        tokenizer.nextToken();  // p
                        tokenizer.nextToken();  // cnf
                        final File file1 = new File(resourceURL.getFile());
                        final int id = Integer.parseInt(file1.getName().substring(0, file1.getName().indexOf('_')));
//                        assertThat(resourceURL.toString().substring(resourceURL.toString().lastIndexOf("_b50_") + 5)).contains(String.valueOf(id));
                        instance = new Instance(id,Integer.parseInt(tokenizer.nextToken()),clausesSize);
                        instance.setKnowSolution(knowSolution);
                        continue;
                    }
                    if(line.startsWith("w")){
                        instance.setWeights(line.substring(2).split(" "));
                        continue;
                    }
                    boolean added = instance.add3LiteralsToClause(Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()), Integer.valueOf(tokenizer.nextToken()));
                    if(!added){
                        break;
                    }
                }
                instances.add(instance);
            } catch (IOException  e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        return instances;
    }
}
